"""
@Author:lichuang
@Create: 2025/10/13
@Last Modified: 2025/10/13
@Last Editor:
@Filename: connect_es.py
@Description: 
"""
from elasticsearch import Elasticsearch, exceptions
from mappings_dict import mapping_template

class ESClient(object):
    def __init__(self, hosts=['http://localhost:9200'], **kwargs):
        self.hosts = hosts
        self.client = None
        self.kwargs = kwargs # 存储额外参数（如 http_auth=("user", "pass")、timeout=30 等）
        self.connect() # 初始化自动连接


    def connect(self):
        """创建es客户端连接"""
        try:
            self.client = Elasticsearch(self.hosts, **self.kwargs)
            # 测试连接是否成功
            if self.client.ping():
                print("es连接成功")
            else:
                print("es连接失败，ping不通")
        except ConnectionError as e:
            print(f"ES 连接异常：{str(e)}")
        except Exception as e:
            print(f"初始化 ES 客户端失败：{str(e)}")
            self.client = None


    def close(self):
        """释放连接资源（ES 客户端无显式 close 方法，此处做清理）"""
        if self.client:
            print("关闭 ES 连接")
            # 注意：elasticsearch-py 客户端没有 close() 方法，底层连接由 urllib3 管理，会自动回收
            # 此处仅做日志记录和状态标记
            self.client = None

    def create_index(self,index,mappings:dict=None,settings:dict=None):
        """
        创建索引（含映射和设置）
        :param index: 索引名
        :param mappings: 映射配置（dict，如 {"properties": {...}}）
        :param settings: 索引设置（dict，如 {"number_of_shards": 3}）
        :return: 响应结果（dict）或 None（失败时）
        """
        if not self.client:
            print("ES 客户端未连接，无法创建索引")
            return None

        if self.exists_hotel_index(index):
            print(f"索引存在，跳过创建{index}")
            return

        try:
            resp = self.client.indices.create( # 发送创建索引请求
                index=index,
                mappings=mappings,
                settings=settings
            )
            print(f"索引创建成功：{index}")
            return resp
        except exceptions.RequestError as e:
            if e.error == "resource_already_exists_exception":
                print(f"索引已存在：{index}（忽略创建）")
            else:
                print(f"创建索引失败（请求错误）：{str(e)}, index={index}")
        except Exception as e:
            print(f"创建索引异常：{str(e)}, index={index}")
        return None

    def delete_index(self,index):
        if not self.client:
            print("ES 客户端未连接，无法创建索引")
            return None

        if not self.exists_hotel_index(index):
            print(f"索引不存在，跳过删除{index}")
            return

        try:
            resp = self.client.indices.delete(index=index)
            print(f"索引删除成功：{index}")
            return resp
        except exceptions.NotFoundError as e:
            print(f"删除失败：索引 {index} 不存在")

        except Exception as e:
            print(f"删除索引异常：{str(e)}, index={index}")


    def exists_hotel_index(self,index):
        """
           检查指定索引是否存在
           :param index: 索引名
           :return: True（存在）/ False（不存在）/ None（客户端未连接或异常）
           """
        if not self.client:
            print("ES 客户端未连接，无法创建索引")
            return None

        exists = self.client.indices.exists(index=index)
        if exists:
            print(f"索引存在：{index}")
            return True
        else:
            print(f"索引不存在：{index}")
            return False


# 单例模式（确保全局只有一个 ES 客户端实例，避免重复连接）
def get_es_client(hosts=["http://localhost:9200"], **kwargs):
    if not hasattr(get_es_client, "_instance"):
        get_es_client._instance = ESClient(hosts=hosts,** kwargs)
    return get_es_client._instance

if __name__ == '__main__':
    es = get_es_client(hosts=["http://localhost:9200"],request_timeout=30)

    # 创建索引
    # es.create_index("hotel",mappings=mapping_template)

    # 删除索引
    # es.delete_index("hotel")

    # 检查索引库是否存在
    # es.exists_hotel_index("hotel")